use ini::Ini;
use serde::{Deserialize, Serialize};
use std::io;
use std::path::{Path, PathBuf};

#[derive(Debug, Serialize, Deserialize)]
pub struct CosConf {
  pub secret_id: String,
  pub secret_key: String,
  pub bucket: String,
  pub region: String,
}

fn expand_tilde<P: AsRef<Path>>(path_user_input: P) -> Option<PathBuf> {
  let p = path_user_input.as_ref();
  if !p.starts_with("~") {
    return Some(p.to_path_buf());
  }
  if p == Path::new("~") {
    return dirs::home_dir();
  }
  dirs::home_dir().map(|mut h| {
    if h == Path::new("/") {
      // Corner case: `h` root directory;
      // don't prepend extra `/`, just drop the tilde.
      p.strip_prefix("~").unwrap().to_path_buf()
    } else {
      h.push(p.strip_prefix("~/").unwrap());
      h
    }
  })
}

impl CosConf {
  pub fn new(secret_id: String, secret_key: String, bucket: String, region: String) -> Self {
    CosConf {
      secret_id,
      secret_key,
      bucket,
      region,
    }
  }

  pub fn read_from_default() -> io::Result<Self> {
    let path = expand_tilde("~/.cos.conf").unwrap();
    Self::read_from_ini(&path)
  }

  pub fn read_from_ini<P: AsRef<Path>>(from_location: P) -> io::Result<Self> {
    let mut conf = Self::new(
      "".to_string(),
      "".to_string(),
      "".to_string(),
      "".to_string(),
    );
    let i = Ini::load_from_file(from_location.as_ref()).unwrap();
    for (sec, prop) in i.iter() {
      if sec.is_some() && sec.unwrap() == "common" {
        for (k, v) in prop.iter() {
          match k {
            "secret_id" => {
              conf.secret_id = v.to_string();
            }
            "secret_key" => {
              conf.secret_key = v.to_string();
            }
            "bucket" => {
              conf.bucket = v.to_string();
            }
            "region" => {
              conf.region = v.to_string();
            }
            _ => {}
          }
        }
      }
    }

    // let content = fs::read_to_string(from_location.as_ref())?;
    // let cos_conf = toml::from_str::<Self>(&content);

    // match cos_conf {
    //   Ok(cos_conf) => Ok(cos_conf),
    //   Err(err) => {
    //     eprint!("err=>{}", err);
    //     panic!("读取cos配置文件失败<{}>", from_location.as_ref().display());
    //   }
    // }

    Ok(conf)
  }
}
